//
// Copyright 2020 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Selector '.mdc-*' should only be used in this project.
// stylelint-disable selector-class-pattern --
// NOTE: this is the implementation of the aforementioned classes.

@use 'sass:math';
@use '@material/dom/mixins' as dom-mixins;
@use '@material/feature-targeting/feature-targeting';
@use '@material/floating-label/mixins' as floating-label-mixins;
@use '@material/floating-label/variables' as floating-label-variables;
@use '@material/list/mixins' as list-mixins;
@use '@material/list/evolution-mixins' as list-evolution-mixins;
@use '@material/touch-target/touch-target';
@use '@material/notched-outline/mixins' as notched-outline-mixins;
@use '@material/notched-outline/variables' as notched-outline-variables;
@use '@material/rtl/rtl';
@use '@material/typography/mixins' as typography-mixins;
@use './select-helper-text-theme';
@use './select-icon-theme';
@use './select-theme';
@use './select-filled';
@use './select-outlined';
@use './select-ripple';
@use './select-helper-text';
@use './select-icon';

@mixin static-styles($query: feature-targeting.all()) {
  @include _static-styles-base($query);
  @include select-filled.static-styles($query);
  @include select-outlined.static-styles($query);
}

@mixin _static-styles-base($query) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select {
    // Floating label private mixin
    @include _floating-label($query: $query);

    @include _option-side-padding(16px, $query: $query);
    @include _option-graphic-trailing-margin(12px, $query: $query);

    @include feature-targeting.targets($feat-structure) {
      display: inline-flex;
      position: relative; // Menu is absolutely positioned relative to this.
      &[hidden] {
        display: none;
      }
    }

    &__dropdown-icon {
      @include _dropdown-icon-base($query: $query);
      @include _dropdown-icon-inactive($query: $query);

      @include feature-targeting.targets($feat-structure) {
        display: inline-flex;
        position: relative;
        align-self: center;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
        pointer-events: none;
      }

      .mdc-select--activated & {
        @include _dropdown-icon-active($query: $query);
      }
    }
  }

  .mdc-select__anchor {
    @include feature-targeting.targets($feat-structure) {
      min-width: 0;
      flex: 1 1 auto;
      position: relative;
      box-sizing: border-box;
      overflow: hidden;
      outline: none;
      cursor: pointer;
    }
  }

  .mdc-select__touch {
    @include touch-target.touch-target($query: $query, $height: 48px);
  }

  @include _text($query: $query);

  .mdc-select--disabled {
    @include _disabled($query: $query);
  }

  .mdc-select--with-leading-icon {
    @include _option-side-padding(12px, $query: $query);
  }

  @include _list($query: $query);

  @include select-filled.core-styles($query: $query);
  @include select-outlined.core-styles($query: $query);
  @include select-ripple.core-styles($query: $query);
  @include select-helper-text.helper-text-core-styles($query: $query);
  @include select-icon.icon-core-styles($query: $query);
}

@mixin core-styles($query: feature-targeting.all()) {
  @include _static-styles-base($query);

  $feat-animation: feature-targeting.create-target($query, animation);
  $feat-color: feature-targeting.create-target($query, color);
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select {
    @include select-theme.ink-color(
      (
        default: select-theme.$ink-color,
        disabled: select-theme.$disabled-ink-color,
      ),
      $query: $query
    );

    @include select-theme.label-color(
      (
        default: select-theme.$label-color,
        focus: select-theme.$focused-label-color,
        disabled: select-theme.$disabled-label-color,
      ),
      $query: $query
    );

    @include select-theme.dropdown-icon-color(
      (
        default: select-theme.$dropdown-icon-color,
        focus: primary,
        disabled: select-theme.$disabled-dropdown-icon-color,
      ),
      $query: $query
    );

    @include select-helper-text-theme.helper-text-color(
      (
        default: select-helper-text-theme.$helper-text-color,
        disabled: select-helper-text-theme.$disabled-helper-text-color,
      ),
      $query: $query
    );

    @include select-icon-theme.icon-color(
      (
        default: select-icon-theme.$icon-color,
        disabled: select-icon-theme.$disabled-icon-color,
      ),
      $query: $query
    );

    // High-contrast mode support
    @include dom-mixins.forced-colors-mode() {
      $gray-text: (
        disabled: GrayText,
      );
      @include select-theme.ink-color($gray-text, $query: $query);
      @include select-theme.dropdown-icon-color($gray-text, $query: $query);
      @include select-theme.label-color($gray-text, $query: $query);
      @include select-theme.bottom-line-color($gray-text, $query: $query);
      @include select-theme.outline-color($gray-text, $query: $query);
      @include select-icon-theme.icon-color($gray-text, $query: $query);
      @include select-helper-text-theme.helper-text-color(
        $gray-text,
        $query: $query
      );
    }

    @include _padding-horizontal(
      $left: select-theme.$anchor-padding-left,
      $left-with-leading-icon:
        select-theme.$anchor-padding-left-with-leading-icon,
      $right: select-theme.$anchor-padding-right,
      $query: $query
    );
    @include select-icon-theme.size(
      select-icon-theme.$icon-size,
      $query: $query
    );
    @include select-theme.dropdown-icon-size(
      select-icon-theme.$icon-size,
      $query: $query
    );

    &__dropdown-icon {
      @include feature-targeting.targets($feat-structure) {
        @include rtl.reflexive-property(
          margin,
          select-icon-theme.$icon-horizontal-margin,
          select-icon-theme.$icon-horizontal-margin
        );
      }
    }
  }

  .mdc-select__anchor {
    @include floating-label-mixins.float-position(
      select-theme.$label-position-y,
      $query: $query
    );

    @include feature-targeting.targets($feat-structure) {
      width: select-theme.$default-width;
    }
  }

  .mdc-select--invalid {
    @include select-theme.label-color(
      (
        default: select-theme.$error-color,
        focus: select-theme.$error-color,
      ),
      $query: $query
    );
    @include select-helper-text-theme.helper-text-validation-color(
      select-theme.$error-color,
      $query: $query
    );
    @include select-theme.dropdown-icon-color(
      (
        default: select-theme.$error-color,
        focus: select-theme.$error-color,
      ),
      $query: $query
    );
  }

  @include _text-container-height($query: $query);
}

@mixin _list($query) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include dom-mixins.forced-colors-mode() {
    .mdc-select__menu::before {
      @include dom-mixins.transparent-border($query: $query);
    }
  }

  .mdc-select__menu .mdc-deprecated-list,
  .mdc-select__menu .mdc-list {
    @include select-icon-theme.icon-horizontal-margins(0, 0, $query: $query);
    @include list-mixins.deprecated-item-selected-text-color(
      on-surface,
      $query: $query
    );
  }

  .mdc-select__menu .mdc-list-item__start {
    @include feature-targeting.targets($feat-structure) {
      display: inline-flex;
      align-items: center;
    }
  }

  .mdc-select__option {
    @include list-evolution-mixins.item-spacing(16px, $query: $query);
  }

  .mdc-select__one-line-option {
    @include list-evolution-mixins.one-line-item-height(48px, $query: $query);
  }

  .mdc-select__two-line-option {
    @include list-evolution-mixins.two-line-item-height(64px, $query: $query);

    &.mdc-list-item--with-two-lines {
      .mdc-list-item__start {
        @include feature-targeting.targets($feat-structure) {
          margin-top: 20px;
        }
      }

      .mdc-list-item__primary-text {
        @include typography-mixins.text-baseline(
          $top: 28px,
          $bottom: 20px,
          $query: $query
        );
      }

      &.mdc-list-item--with-trailing-meta .mdc-list-item__end {
        @include typography-mixins.text-baseline($top: 36px, $query: $query);
      }
    }
  }

  .mdc-select__option-with-leading-content {
    @include list-evolution-mixins.item-start-spacing(12px, 0, $query: $query);
    @include list-evolution-mixins.item-start-size(36px, 24px, $query: $query);
    @include list-evolution-mixins.item-spacing(0, 12px, $query: $query);
  }

  .mdc-select__option-with-meta {
    @include list-evolution-mixins.item-end-spacing(12px, $query: $query);
  }
}

///
/// Sets base dropdown icon styles.
/// @access private
///
@mixin _dropdown-icon-base($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select__dropdown-icon-active,
  .mdc-select__dropdown-icon-inactive {
    @include feature-targeting.targets($feat-structure) {
      position: absolute;
      top: 0;
      left: 0;
    }
  }

  .mdc-select__dropdown-icon-graphic {
    $svg-natural-width: 10px;
    $svg-natural-height: 5px;

    @include feature-targeting.targets($feat-structure) {
      width: math.div($svg-natural-width, select-icon-theme.$icon-size) * 100%;
      height: math.div($svg-natural-height, select-icon-theme.$icon-size) * 100%;
    }
  }
}

///
/// Sets styles for transitioning the dropdown icon to inactive state.
/// @access private
///
@mixin _dropdown-icon-inactive($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);
  $feat-animation: feature-targeting.create-target($query, animation);

  .mdc-select__dropdown-icon-inactive {
    @include feature-targeting.targets($feat-structure) {
      opacity: 1;
    }

    @include feature-targeting.targets($feat-animation) {
      transition: opacity select-theme.$icon-inactive-fade-in-duration linear
        select-theme.$icon-inactive-fade-out-duration;
    }
  }

  .mdc-select__dropdown-icon-active {
    @include feature-targeting.targets($feat-structure) {
      opacity: 0;
    }

    @include feature-targeting.targets($feat-animation) {
      transition: opacity select-theme.$icon-inactive-fade-out-duration linear;
    }
  }
}

///
/// Sets styles for transitioning the dropdown icon to activated state.
/// @access private
///
@mixin _dropdown-icon-active($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);
  $feat-animation: feature-targeting.create-target($query, animation);

  .mdc-select__dropdown-icon-inactive {
    @include feature-targeting.targets($feat-structure) {
      opacity: 0;
    }

    @include feature-targeting.targets($feat-animation) {
      transition: opacity select-theme.$icon-active-fade-out-duration linear;
    }
  }

  .mdc-select__dropdown-icon-active {
    @include feature-targeting.targets($feat-structure) {
      opacity: 1;
    }

    @include feature-targeting.targets($feat-animation) {
      transition: opacity select-theme.$icon-active-fade-in-duration linear
        select-theme.$icon-active-fade-out-duration;
    }
  }
}

///
/// Sets the side padding for option text.
/// @access private
///
@mixin _option-side-padding($side-padding, $query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select__menu .mdc-deprecated-list-item {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.reflexive-property(padding, $side-padding, $side-padding);
    }
  }
}

///
/// Sets the traliing margin for an option's leading graphic.
/// @access private
///
@mixin _option-graphic-trailing-margin(
  $margin-right,
  $query: feature-targeting.all()
) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select__menu .mdc-deprecated-list-item__graphic {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.reflexive-box(margin, right, $margin-right);
    }
  }
}

@mixin _floating-label($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-floating-label {
    @include feature-targeting.targets($feat-structure) {
      top: 50%;
      transform: translateY(-50%);
      pointer-events: none;
    }
  }
}

@mixin _text-container-height($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select__selected-text-container {
    @include feature-targeting.targets($feat-structure) {
      height: select-theme.$selected-text-height;
    }
  }
}

@mixin _text($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);
  $feat-color: feature-targeting.create-target($query, color);

  .mdc-select__selected-text-container {
    @include feature-targeting.targets($feat-structure) {
      display: flex;
      appearance: none;
      pointer-events: none;
      box-sizing: border-box;
      width: auto;
      min-width: 0;
      flex-grow: 1;
      border: none;
      outline: none;
      padding: 0;
    }

    @include feature-targeting.targets($feat-color) {
      background-color: transparent;
      color: inherit; // Override default user agent stylesheet
    }
  }

  .mdc-select__selected-text {
    @include typography-mixins.typography(subtitle1, $query: $query);
    @include typography-mixins.overflow-ellipsis($query: $query);

    @include feature-targeting.targets($feat-structure) {
      display: block;
      width: 100%;
      @include rtl.ignore-next-line();
      text-align: left;
      @include rtl.rtl {
        @include rtl.ignore-next-line();
        text-align: right;
      }
    }
  }
}

@mixin _disabled($query: feature-targeting.all()) {
  $feat-structure: feature-targeting.create-target($query, structure);

  @include feature-targeting.targets($feat-structure) {
    cursor: default;
    pointer-events: none;
  }
}

/// Adds horizontal padding to the selected text
///
/// @param {Number} $left - left side padding
/// @param {Number} $left-with-leading-icon - left-side padding when a leading
///     icon is present
/// @param {Number} $right - right-side padding; note that a trailing icon is
///     always present.
@mixin _padding-horizontal(
  $left,
  $left-with-leading-icon,
  $right,
  $query: feature-targeting.all()
) {
  $feat-structure: feature-targeting.create-target($query, structure);

  .mdc-select__anchor {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.reflexive-property(padding, $left, $right);
    }
  }

  &.mdc-select--with-leading-icon .mdc-select__anchor {
    @include feature-targeting.targets($feat-structure) {
      @include rtl.reflexive-property(padding, $left-with-leading-icon, $right);
    }
  }
}
